/*
 * Copyright (c) Jiandong.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import buffer from '@ohos.buffer';
import systemTime from '@ohos.systemTime';
import ArrayList from '@ohos.util.ArrayList';
import hilog from '@ohos.hilog';
import worker from '@ohos.worker';

import { reactNativeBundle }  from './BridgeReactNativeDevBundle'

//import reactHarmony from 'libreactharmony.so'

import { SoLoader, NativeModuleRegistry, NativeModuleRegistryBuilder, UIManagerModule, Communication, ReactContextService, ReactInstanceManagerService } from 'ReactHarmony';

//hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', reactHarmony.add(2, 3));
//hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', reactHarmony.add(2, 3));

let reactContextService: ReactContextService = null;

//const CreateContext: number = -1
//const RunBundle: number = 0
//const RunApplication: number = 1
//const ProcessPackages: number = 2
//const OnHostForeground: number = 3

//const UIManagerModuleMessage = 1
//const CreateView: number = 0
//const UpdateView: number = 1

const TAG: string = "React Worker Test"

hilog.info(0x0000, "worker", "worker test");
const parentPort = worker.workerPort;
parentPort.onmessageerror = function (e) {
    hilog.info(0x0000, TAG, "worker.js onmessage error")
}
parentPort.onmessage = function (e) {
    switch (e.data.message) {
        case Communication.InitializeRuntime:
            initJsRuntime();
        case Communication.CreateAndSetUpContext:
            createAndSetupContext();
            break;
        case Communication.ProcessPackages:
            processPackages();
            break;
        case Communication.RunBundleFromFile:
            runBundleFromFile(e.data.file as string);
            break;
        case Communication.RunBundleFromBuffer:
            runBundleFromBuffer(e.data.buffer as ArrayBuffer )
            break;
        case Communication.RunApplication:
            runApplication();
            break;
        case Communication.OnHostForeground:
            onHostForeground();
            break;
        default:
            hilog.error(0x0000, TAG, '%{public}s', e.data.message);
            break;
    }
}

function initJsRuntime() {

}

function createAndSetupContext() {
    hilog.info(0x0000, TAG, '%{public}s', "createAndSetupContext");
    reactContextService = new ReactContextService();
    systemTime.getCurrentTime(true, (error, data) => {
        if (error) {
            console.error(`failed to systemTime.getCurrentTime because ` + JSON.stringify(error));
            return;
        }
        parentPort.dispatchEvent({ type: Communication.CreateAndSetUpContextFinished, timeStamp: data as number })
        console.log(`systemTime.getCurrentTime success data : ` + JSON.stringify(data));
    });
}

function runBundleFromFile(filePath: string) {
    hilog.info(0x0000, TAG, '%{public}s', "runBundleFromFile");
    SoLoader.napiRunScriptFromFilePath(filePath) //
        reactNativeBundle();
}

function runBundleFromBuffer(buffer: ArrayBuffer) {
    hilog.info(0x0000, TAG, '%{public}s', "loadScriptFromBuffer 2222");
    SoLoader.napiRunScriptFromArrayBuffer(buffer);
    registerUI();
}

function runApplication() {
    hilog.info(0x0000, TAG, '%{public}s', "RunApplication");
    createView();
    updateView()
}

function registerUI() {
}

function onHostForeground() {

}

//['clearJSResponder', 'configureNextLayoutAnimation', 'createView', 'dismissPopupMenu', 'dispatchViewManagerCommand', 'findSubviewIn', 'getConstantsForViewManager', 'getDefaultEventTypes', 'manageChildren', 'measure', 'measureInWindow', 'measureLayout', 'measureLayoutRelativeToParent', 'removeRootView', 'removeSubviewsFromContainerWithID', 'replaceExistingNonRootView', 'sendAccessibilityEvent', 'setChildren', 'setJSResponder', 'setLayoutAnimationEnabledExperimental', 'showPopupMenu', 'updateView', 'viewIsDescendantOf', 'PopupMenu', 'LazyViewManagersEnabled', 'ViewManagerNames', 'StyleConstants', 'AccessibilityEventTypes', 'UIView', 'getViewManagerConfig', 'hasViewManagerConfig', 'blur', 'focus', 'genericBubblingEventTypes', 'genericDirectEventTypes', 'lazilyLoadView'];

//
function createView() {
    hilog.info(0x0000, TAG, 'CreateUIInstance %{public}d', 11)
    let uiManager = reactContextService.getNativeModuleRegistry().getModule("uiManager") as UIManagerModule
    // uiManager.createView(1, "text", 0, null)
    //    parentPort.postMessage({message: "CreateUIInstance", type: "text"})
    parentPort.postMessage({ message: Communication.UIManagerModuleMessage, data: { message: Communication.CreateView, tag: 1, type: "RCTText" }})
}

function updateView() {
    hilog.info(0x0000, TAG, 'UpdateUIInstance %{public}d', 11)
    let uiManager = reactContextService.getNativeModuleRegistry().getModule("uiManager") as UIManagerModule
    // uiManager.updateView(1, "text", 0)
    // parentPort.postMessage({message: "UpdateUIInstance"})
    parentPort.postMessage({ message: Communication.UIManagerModuleMessage, data: { message: Communication.UpdateView, tag: 1 }})
}

function manageChildren() {

}

function setChildren() {

}

function processPackages() {
    hilog.info(0x0000, TAG, "processPackages %{public}d", 11);
    let nativeModuleRegistryBuilder = new NativeModuleRegistryBuilder(null, null);
    //todo:should move to turbo module
    nativeModuleRegistryBuilder.processPackage(null);
    //      for (let reactPackage of packages) {
    //        hilog.info(0x0000, ReactInstanceManager.TAG, 'constructor 0000000');
    //          if (checkAndUpdatePackageMembership && this.mPackages.has(reactPackage as ReactPackage)) {
    //            continue;
    //          }
    //        hilog.info(0x0000, ReactInstanceManager.TAG, 'constructor aaaaa');
    ////          Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "createAndProcessCustomReactPackage");
    //          try {
    //            hilog.info(0x0000, ReactInstanceManager.TAG, 'constructor bbbbbbb');
    //            if (checkAndUpdatePackageMembership) {
    //              this.mPackages.add(reactPackage);
    //            }
    //            hilog.info(0x0000, ReactInstanceManager.TAG, 'constructor ccccccc');
    //            this.processPackage(reactPackage, nativeModuleRegistryBuilder);
    //            hilog.info(0x0000, ReactInstanceManager.TAG, 'constructor ddddddd');
    //          } finally {
    ////            Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
    //          }
    //      }

    hilog.info(0x0000, TAG, "processPackages %{public}d", 222);
    reactContextService.setNativeModuleRegistry(nativeModuleRegistryBuilder.build())
    // parentPort.dispatchEvent({type: "processPackages", timeStamp: 111})
    hilog.info(0x0000, TAG, "processPackages %{public}d", 333);
}